#include "RX8010.h"
dateTime getDateTime()
{
    u_char ti[7], i;
    dateTime dt;
    Wire.beginTransmission(RX8010_ADDR); // 开启发送
    Wire.write(0x10);                    // 写入 DS1307 秒地址
    Wire.endTransmission();              //  结束发送
    Wire.requestFrom(RX8010_ADDR, 7, 1); // 请求 7个字节并停止
    i = 0;
    while (Wire.available())
    {                                          // 可否获取1个数据
        ti[i++] = bcd2dec(Wire.read() & 0x7F); // 读取 DS1307 秒
    }
    dt.year = ti[6];
    dt.month = ti[5];
    dt.date = ti[4];
    dt.day = ti[3];
    dt.hour = ti[2];
    dt.minute = ti[1];
    dt.second = ti[0];
    return dt;
}
void setTime(dateTime dt)
{
    Wire.beginTransmission(RX8010_ADDR); // 开启发送
    Wire.write(0x10);                    // 写入 DS1307 秒地址

    Wire.write(dec2bcd(dt.second));
    Wire.write(dec2bcd(dt.minute));
    Wire.write(dec2bcd(dt.hour));

    Wire.write(dec2bcd(dt.day));
    Wire.write(dec2bcd(dt.date));
    Wire.write(dec2bcd(dt.month));
    if (dt.year > 2000)
        dt.year = dt.year - 2000;
    Wire.write(dec2bcd(dt.year));
    Wire.endTransmission();
}
byte readFromModule(byte address)
{
    Wire.beginTransmission(RX8010_ADDR);
    Wire.write(address);
    Wire.endTransmission();
    Wire.requestFrom(RX8010_ADDR, 1);

    if (Wire.available())
    {
        return Wire.read();
    }

    return -1;
}
byte setBinary(byte binary, byte pos, byte flagVal)
{
    if (flagVal == 1)
    {
        return binary | (1 << pos);
    }

    return binary & (~(1 << pos));
}
void writeToModule(byte address, byte data)
{
    Wire.beginTransmission(RX8010_ADDR);
    Wire.write(address);
    Wire.write(data);
    Wire.endTransmission();
}
void writeFlag(byte address, byte pos, byte value)
{
    byte addressValue = readFromModule(address);
    addressValue = setBinary(addressValue, pos, value);
    writeToModule(address, addressValue);
}
void disableFCT()
{
    writeFlag(RX8010_EXT, RX8010_TE_POS, 0);
    writeFlag(RX8010_CTRL, RX8010_TSTP_POS, 1);
}
void setFCT(byte pin, uint16_t multiplier, byte frequency)
{
    if (pin > 1)
    {
        writeFlag(RX8010_CTRL, RX8010_TIE_POS, 0);
    }
    else
    {
        writeFlag(RX8010_IRQ, RX8010_TMPIN_POS, pin);
        writeFlag(RX8010_CTRL, RX8010_TIE_POS, 1);
    }
    byte firstHalf = multiplier & 0b11111111;
    byte secondHalf = multiplier >> 8;

    writeToModule(RX8010_TCOUNT0, firstHalf);
    writeToModule(RX8010_TCOUNT1, secondHalf);

    writeFlag(RX8010_EXT, RX8010_TSEL0_POS, getValueFromBinary(frequency, RX8010_TSEL0_POS));
    writeFlag(RX8010_EXT, RX8010_TSEL1_POS, getValueFromBinary(frequency, RX8010_TSEL1_POS));
    writeFlag(RX8010_EXT, RX8010_TSEL2_POS, getValueFromBinary(frequency, RX8010_TSEL2_POS));
	//enable FCT
	writeFlag(RX8010_CTRL, RX8010_TSTP_POS, 0);
    writeFlag(RX8010_CTRL, RX8010_TIE_POS, 1);
    writeFlag(RX8010_EXT, RX8010_TE_POS, 1);
}
/* void setFCTOutput(byte pin)
{
    if (pin > 1)
    {
        writeFlag(RX8010_CTRL, RX8010_TIE_POS, 0);
    }
    else
    {
        writeFlag(RX8010_IRQ, RX8010_TMPIN_POS, pin);
        writeFlag(RX8010_CTRL, RX8010_TIE_POS, 1);
    }
}
void setFCTCounter(uint16_t multiplier, byte frequency)
{
    byte firstHalf = multiplier & 0b11111111;
    byte secondHalf = multiplier >> 8;

    writeToModule(RX8010_TCOUNT0, firstHalf);
    writeToModule(RX8010_TCOUNT1, secondHalf);

    writeFlag(RX8010_EXT, RX8010_TSEL0_POS, getValueFromBinary(frequency, RX8010_TSEL0_POS));
    writeFlag(RX8010_EXT, RX8010_TSEL1_POS, getValueFromBinary(frequency, RX8010_TSEL1_POS));
    writeFlag(RX8010_EXT, RX8010_TSEL2_POS, getValueFromBinary(frequency, RX8010_TSEL2_POS));
} */
byte getValueFromBinary(byte binary, byte pos)
{
    return ((binary >> pos) & 1) == 1 ? 1 : 0;
}
/*void enableFCT()
{
    writeFlag(RX8010_CTRL, RX8010_TSTP_POS, 0);
    writeFlag(RX8010_CTRL, RX8010_TIE_POS, 1);
    writeFlag(RX8010_EXT, RX8010_TE_POS, 1);
}*/
void resetRX8010()
{
    writeToModule(RX8010_RESV17, RX8010_ADDR17_DEF_VAL);
    writeToModule(RX8010_RESV30, RX8010_ADDR30_DEF_VAL);
    writeToModule(RX8010_RESV31, RX8010_ADDR31_DEF_VAL);
    writeToModule(RX8010_IRQ, RX8010_IRQ_DEF_VAL);

    writeFlag(RX8010_EXT, RX8010_TE_POS, 0);
    writeFlag(RX8010_FLAG, RX8010_VLF_POS, 0);

    writeToModule(RX8010_CTRL, RX8010_CTRL_DEF_VAL);
}
uint8_t dec2bcd(uint8_t dec)
{
    return ((dec / 10 * 16) + (dec % 10));
}

uint8_t bcd2dec(uint8_t bcd)
{
    return ((bcd / 16 * 10) + (bcd % 16));
}
void enableFOUT(byte pin, byte frequency)
{
    switch (frequency)
    {
    case 3:
        writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 1);
        writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 1);
        break;
    case 2:
        writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 0);
        writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 1);
        break;
    case 1:
        writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 1);
        writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 0);
        break;
    case 0:
    default:
        disableFOUT();
        return;
    }

    writeFlag(RX8010_IRQ, RX8010_FOPIN0_POS, pin == 1 ? 1 : 0);
    writeFlag(RX8010_IRQ, RX8010_FOPIN1_POS, 0);
}

void disableFOUT()
{
    writeFlag(RX8010_EXT, RX8010_FSEL0_POS, 0);
    writeFlag(RX8010_EXT, RX8010_FSEL1_POS, 0);
}
void setTUIMode(bool minute)
{
    writeFlag(RX8010_EXT, RX8010_USEL_POS, minute ? 1 : 0);
}

void enableTUI()
{
    writeFlag(RX8010_CTRL, RX8010_UIE_POS, 1);
}

void disableTUI()
{
    writeFlag(RX8010_CTRL, RX8010_UIE_POS, 0);
}

bool checkTUI()
{
    byte flag = readFromModule(RX8010_FLAG);
    bool interrupted = getValueFromBinary(flag, RX8010_UF_POS) == 1;

    if (interrupted)
    {
        writeFlag(RX8010_FLAG, RX8010_UF_POS, 0);
    }

    return interrupted;
}
